package com.hyk.aspect;

import cn.hutool.core.lang.Snowflake;
import com.hyk.ann.RequestType;
import com.hyk.domain.SysUserLog;
import com.hyk.enums.RequestTypeEnum;
import com.hyk.service.SysUserLogService;
import com.hyk.utils.IpUtils;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;

@Aspect
@Order(2)
@Component
@Slf4j
public class WebAdminLogAspect {

    private static final String defDescription = "该方法没有描述";
    private static final Long defUserId = 0L;

    private Snowflake snowflake = new Snowflake(1,1);

    @Autowired
    private SysUserLogService sysUserLogService;

    @Pointcut("execution(* com.hyk.controller.*.*(..))")
    public void setWebLogAspectPotcut(){

    }

    //ProceedingJoinPoint 这个是就代表目标方法
    @Around(value = "setWebLogAspectPotcut()")
    public Object aroundAdvice(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {

        SysUserLog sysUserLog = new SysUserLog();

        MethodSignature signature = (MethodSignature) proceedingJoinPoint.getSignature();
        Method method = signature.getMethod();

        ApiOperation annotation = method.getAnnotation(ApiOperation.class);
        RequestType requestType = method.getAnnotation(RequestType.class);

        if(requestType == null){
            sysUserLog.setGroup(RequestTypeEnum.DEFAULT.getMsg());
        }else {
            sysUserLog.setGroup(requestType.value().getMsg());
        }

        //设置方法的描述
        if(annotation == null){
            sysUserLog.setDescription(defDescription);
        }
        else {
            String value = annotation.value();
            sysUserLog.setDescription(StringUtils.isBlank(value) ? defDescription :value);
        }

        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        //设置用户
        long userId = 0L;
        try{
            userId = Long.parseLong(authentication.getPrincipal().toString());
            sysUserLog.setUserId(userId);
        }catch (Exception e){
            userId=0L;
        }

        //设置方法的消耗时间
        Object result = null;
        StopWatch stopWatch = new StopWatch(); // 创建计时器
        stopWatch.start(); //  开始计时器
        result = proceedingJoinPoint.proceed(proceedingJoinPoint.getArgs()); // 不需要我们自己处理这个异常
        stopWatch.stop(); // 记时结束

        //设置方法的消耗时间
        sysUserLog.setTime(stopWatch.getTotalTimeMillis());

        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();

        HttpServletRequest request = requestAttributes.getRequest();

        sysUserLog.setId(snowflake.nextId());
        sysUserLog.setIp(IpUtils.getIpAddr(request));
        sysUserLog.setMethod(request.getMethod());
        sysUserLog.setRemark(sysUserLog.getDescription());

        sysUserLogService.save(sysUserLog);
        return result;

    }
}
